/**
 * 飞机航行案例
 *
 * 这个文件演示了如何使用 OpenSky Network API 获取实时飞机数据，
 * 并在 Cesium 地球上显示亚洲地区的飞机位置。
 *
 * 功能包括：
 * 1. 从 OpenSky Network API 获取亚洲地区的实时飞机数据
 * 2. 在地球上显示飞机的位置
 * 4. 定时更新飞机位置
 */

import * as Cesium from "cesium";
import "cesium/Build/Cesium/Widgets/widgets.css";

// 飞机实体集合，用于管理所有飞机实体
let airplaneEntities = {};
// 定时更新的计时器ID
let updateTimerId = null;
// 更新间隔（毫秒）
const UPDATE_INTERVAL = 15000; // 15秒，减少请求频率

// 亚洲地区的经纬度范围
const ASIA_BOUNDS = {
  west: 25.0, // 最西经度（中东地区）
  east: 150.0, // 最东经度（亚洲东部）
  south: 0.0, // 最南纬度（东南亚南部）
  north: 60.0, // 最北纬度（俄罗斯亚洲部分）
};

/**
 * 根据飞机的高度或速度获取颜色
 * @param {number} altitude 飞机高度（米）
 * @returns {Cesium.Color} 颜色对象
 */
function getAirplaneColor(altitude) {
  // 使用更加美观的颜色方案
  if (altitude > 10000) {
    // 高空飞行 - 靓丽的深蓝色
    return new Cesium.Color(0.0, 0.4, 0.8, 1.0);
  } else if (altitude > 5000) {
    // 中高空飞行 - 优雅的紫色
    return new Cesium.Color(0.6, 0.2, 0.8, 1.0);
  } else if (altitude > 2000) {
    // 中低空飞行 - 温暖的橙色
    return new Cesium.Color(1.0, 0.6, 0.0, 1.0);
  } else {
    // 低空飞行 - 鲜艳的红色
    return new Cesium.Color(0.9, 0.2, 0.2, 1.0);
  }
}

/**
 * 从本地data.json文件获取飞机数据
 * @returns {Promise<Array>} 飞机数据数组
 */
async function fetchAirplaneData() {
  // 使用绝对路径或import.meta.url来确保正确加载data.json
  // 方法1：使用import.meta.url获取当前模块的URL，然后构建相对路径
  const baseUrl = new URL(".", import.meta.url).href;
  const dataUrl = new URL("data.json", baseUrl).href;

  console.log("尝试从以下路径加载数据:", dataUrl);

  const response = await fetch(dataUrl);
  if (!response.ok) {
    throw new Error(`HTTP 错误! 状态: ${response.status}`);
  }
  const data = await response.json();

  // 筛选只在亚洲地区的飞机数据
  const asiaStates = data.states
    ? data.states.filter((airplane) => {
        // 飞机数据格式: [icao24, callsign, origin_country, time_position, last_contact, longitude, latitude, ...]
        const longitude = airplane[5]; // 经度
        const latitude = airplane[6]; // 纬度

        // 检查经纬度是否在亚洲范围内
        return (
          longitude !== null &&
          latitude !== null &&
          longitude >= ASIA_BOUNDS.west &&
          longitude <= ASIA_BOUNDS.east &&
          latitude >= ASIA_BOUNDS.south &&
          latitude <= ASIA_BOUNDS.north
        );
      })
    : [];

  console.log(
    `已从本地数据文件加载 ${
      data.states ? data.states.length : 0
    } 架飞机数据，` + `筛选出亚洲地区的 ${asiaStates.length} 架飞机`
  );

  return asiaStates;
}

/**
 * 创建飞机实体
 * @param {Cesium.Viewer} viewer Cesium Viewer 实例
 * @param {Array} airplaneData 单架飞机的数据
 * @returns {Cesium.Entity} 创建的飞机实体
 */
function createAirplaneEntity(viewer, airplaneData) {
  // 飞机数据格式: [icao24, callsign, origin_country, time_position, last_contact, longitude, latitude, baro_altitude, on_ground, velocity, true_track, vertical_rate, sensors, geo_altitude, squawk, spi, position_source]
  const icao24 = airplaneData[0]; // 飞机唯一标识
  const callsign = airplaneData[1] ? airplaneData[1].trim() : "未知航班";
  const country = airplaneData[2] || "未知国家";
  const longitude = airplaneData[5]; // 经度
  const latitude = airplaneData[6]; // 纬度
  const altitude = airplaneData[7] || 0; // 高度（米）
  const heading = airplaneData[10] || 0; // 航向（度）

  // 如果没有位置数据，则跳过
  if (!longitude || !latitude) {
    return null;
  }

  // 获取飞机颜色
  const airplaneColor = getAirplaneColor(altitude);

  // 如果飞机实体已存在，直接返回，不进行更新
  if (airplaneEntities[icao24]) {
    return airplaneEntities[icao24];
  }

  // 创建新的飞机实体
  const entity = viewer.entities.add({
    id: icao24,
    name: `${callsign} (${country})`,
    position: Cesium.Cartesian3.fromDegrees(longitude, latitude, altitude),
    orientation: Cesium.Transforms.headingPitchRollQuaternion(
      Cesium.Cartesian3.fromDegrees(longitude, latitude, altitude),
      new Cesium.HeadingPitchRoll(Cesium.Math.toRadians(heading), 0, 0)
    ),
    // 飞机模型
    model: {
      uri: "https://raw.githubusercontent.com/CesiumGS/cesium/main/Apps/SampleData/models/CesiumAir/Cesium_Air.glb",
      minimumPixelSize: 32,
      maximumScale: 20000,
      scale: 0.5,
      color: airplaneColor,
      colorBlendMode: Cesium.ColorBlendMode.MIX, // 改为MIX模式，让颜色更自然
      colorBlendFactor: 0.7, // 颜色混合因子，调整模型原始颜色与设定颜色的混合比例
    },
    // 飞机标签
    label: {
      text: callsign,
      font: "14px sans-serif",
      style: Cesium.LabelStyle.FILL_AND_OUTLINE,
      outlineWidth: 2,
      verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
      pixelOffset: new Cesium.Cartesian2(0, -30),
      distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 100000),
      disableDepthTestDistance: Number.POSITIVE_INFINITY,
      fillColor: airplaneColor,
      outlineColor: Cesium.Color.BLACK,
    },
  });

  airplaneEntities[icao24] = entity;
  return entity;
}

/**
 * 更新所有飞机的位置
 * @param {Cesium.Viewer} viewer Cesium Viewer 实例
 */
async function updateAirplanes(viewer) {
  const airplaneData = await fetchAirplaneData();

  // 更新或创建飞机实体
  for (const airplane of airplaneData) {
    const icao24 = airplane[0];
    if (icao24) {
      console.log(icao24);
      createAirplaneEntity(viewer, airplane);
    }
  }
}

// 导出初始化函数，供主程序调用
export async function init(container) {
  // 配置 Cesium Ion 访问令牌
  Cesium.Ion.defaultAccessToken = import.meta.env.VITE_CESIUM_ION_TOKEN;

  // 创建 Cesium Viewer 实例
  const viewer = new Cesium.Viewer(container, {});

  // 设置初始相机位置 - 飞向亚洲上空
  viewer.camera.flyTo({
    destination: Cesium.Cartesian3.fromDegrees(100.0, 35.0, 6000000), // 亚洲中部上空
    orientation: {
      heading: Cesium.Math.toRadians(0.0),
      pitch: Cesium.Math.toRadians(-60.0), // 俯视角度
    },
    duration: 3,
  });

  // 初始加载飞机数据
  await updateAirplanes(viewer);

  // 添加鼠标点击事件，点击飞机时自动跟随
  viewer.screenSpaceEventHandler.setInputAction((click) => {
    const pickedObject = viewer.scene.pick(click.position);
    if (Cesium.defined(pickedObject) && pickedObject.id) {
      const entity = pickedObject.id;
      if (airplaneEntities[entity.id]) {
        // 跟随选中的飞机
        viewer.trackedEntity = entity;
      }
    }
  }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

  // 添加双击事件，双击时取消跟随
  viewer.screenSpaceEventHandler.setInputAction(() => {
    viewer.trackedEntity = undefined;
  }, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);

  // 返回 viewer 实例，以便外部可以进一步操作
  return viewer;
}

// 导出清理函数，在切换案例时调用
export function cleanup(viewer) {
  // 清除定时器
  if (updateTimerId) {
    clearInterval(updateTimerId);
    updateTimerId = null;
  }

  // 清除飞机实体
  airplaneEntities = {};

  // 销毁 viewer
  if (viewer) {
    viewer.destroy();
  }
}
